package com.zzs.common.security.service.impl;

import com.zzs.common.core.constant.JwtConsts;
import com.zzs.common.core.constant.RedisKeyConsts;
import com.zzs.common.core.enums.ResponseCode;
import com.zzs.common.core.enums.UserRole;
import com.zzs.common.redis.service.RedisService;
import com.zzs.common.security.exception.ServiceException;
import com.zzs.common.security.service.TokenService;
import com.zzs.common.security.util.JwtProvider;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

/**
 * Token 服务实现类，提供基于 JWT 和 Redis 的用户身份管理。
 * @date 2025/03/17
 * @author zzs
 */
@Service
public class TokenServiceImpl implements TokenService {
    @Autowired
    private RedisService redisService;
    @Autowired
    private JwtProvider jwtProvider;

    @Override
    public String createToken(long userId, UserRole userRole) {
        String token = jwtProvider.createToken(userId);
        redisService.saveValue(RedisKeyConsts.getUserLoginKey(userId), userRole.getRole(), RedisKeyConsts.USER_LOGIN_EXPIRE_TIME, RedisKeyConsts.USER_LOGIN_TIME_UNIT);
        return token;
    }

    @Override
    public int getUserRole(long userId) {
        Integer role = redisService.getValue(RedisKeyConsts.getUserLoginKey(userId), Integer.class);
        if (role == null) {
            throw new ServiceException(ResponseCode.UNAUTHORIZED);
        }
        return role;
    }

    @Override
    public long getUserId(String authHeader) {
        String token = extractToken(authHeader);
        Long userId = jwtProvider.getUserId(token);
        if (userId == null) {
            throw new ServiceException(ResponseCode.UNAUTHORIZED);
        }
        return userId;
    }

    @Override
    public String refreshCacheAndCreateNewToken(long userId) {
        String redisKey = RedisKeyConsts.getUserLoginKey(userId);
        redisService.expire(redisKey, RedisKeyConsts.USER_LOGIN_EXPIRE_TIME, RedisKeyConsts.USER_LOGIN_TIME_UNIT);
        return jwtProvider.createToken(userId);
    }

    @Override
    public void removeCache(long userId) {
        boolean b = redisService.removeKey(RedisKeyConsts.getUserLoginKey(userId));
        if (!b) {
            throw new ServiceException(ResponseCode.NOT_FOUND);
        }
    }

    @Override
    public long getRemainingTime(String authHeader) {
        String token = extractToken(authHeader);
        return jwtProvider.getRemainingTime(token);
    }

    /**
     * 提取 Authorization 头部中的 Token
     *
     * @param authHeader Authorization 头部
     * @return 提取后的 Token
     * @throws ServiceException 若 Authorization 头部无效
     */
    private String extractToken(String authHeader) {
        if (authHeader != null && authHeader.startsWith(JwtConsts.BEARER_PREFIX)) {
            return authHeader.replaceFirst(JwtConsts.BEARER_PREFIX, "");
        }
        throw new ServiceException(ResponseCode.UNAUTHORIZED);
    }
}
